package com.example.neuronview

import android.content.res.Configuration
import android.content.res.Configuration.ORIENTATION_LANDSCAPE
import android.database.DataSetObserver
import android.opengl.GLSurfaceView
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.widget.LinearLayout
import android.widget.ListView
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.example.neuronview.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity() {
    private val sampleList = mutableListOf<Sample>()
    private var originSampleList = mutableListOf<Sample>()
    private val neuronList = mutableListOf<Neuron>()
    private lateinit var binding: ActivityMainBinding
    private lateinit var sampleAdapter: SampleAdapter
    private lateinit var sampleListView: ListView
    private lateinit var sampleSearch: TextView
    private lateinit var neuronAdapter: NeuronAdapter
    private lateinit var neuronListView: ListView
    private lateinit var neuronRenderer: NeuronRenderer
    private val httpData = HttpData(this)

    fun changeOrientation(orientation: Int) {
        val linearLayout = findViewById<LinearLayout>(R.id.rootLayout)
        linearLayout.orientation = orientation
        val listLayout = findViewById<LinearLayout>(R.id.listLayout)
        listLayout.orientation =
            if (orientation == 1) LinearLayout.HORIZONTAL else LinearLayout.VERTICAL
    }

    override fun onConfigurationChanged(newConfig: Configuration) {
        super.onConfigurationChanged(newConfig)
        when {

            newConfig.orientation == ORIENTATION_LANDSCAPE -> {
                changeOrientation(0)
            }

            else -> {
                changeOrientation(1)
            }
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        onConfigurationChanged(resources.configuration)

        val mousemodelStream = assets.open("997.obj")
        val mesh = parseObjStream(mousemodelStream)



        initSampleList()
        initNeuronList()
        val selectAll = binding.ckSelectAll
        selectAll.setOnCheckedChangeListener { _, isChecked ->
            neuronAdapter.selectAllCoroutine(isChecked)
        }

        val glSurfaceView = binding.glSurfaceView
        glSurfaceView.renderMode = GLSurfaceView.RENDERMODE_WHEN_DIRTY
        neuronRenderer = glSurfaceView.getNeuronRenderer() as NeuronRenderer
        neuronRenderer.setMesh(mesh)

    }

    override fun onDestroy() {
        super.onDestroy()
        httpData.cancelAllRequests()
    }

    private val neuronObserver = object : DataSetObserver() {
        override fun onChanged() {
            super.onChanged()
            binding.neuronCount.text = neuronList.size.toString()
        }

        override fun onInvalidated() {
            super.onInvalidated()
            binding.neuronCount.text = neuronList.size.toString()

        }
    }

    fun initNeuronList() {
        neuronListView = binding.neuronListView
        neuronAdapter = NeuronAdapter(this, neuronList)
        neuronAdapter.onCheckBoxStateChanged = { position, isChecked, item, color ->
            if (isChecked)
                neuronRenderer.addNeuron(item, color)
            else
                neuronRenderer.removeNeuron(item)
        }
        neuronListView.adapter = neuronAdapter
        neuronAdapter.registerDataSetObserver(neuronObserver)
    }

    private val sampleSearchWatcher: TextWatcher = object : TextWatcher {
        override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
//                sampleList.clear()
        }

        override fun afterTextChanged(s: Editable?) {
            sampleList.clear()
            sampleList.addAll(originSampleList.filter { it.sampleid.contains(s.toString()) })
            sampleAdapter.notifyDataSetChanged()
        }

        override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
        }
    }

    fun initSampleList() {
        sampleSearch = binding.sampleSearch
        sampleSearch.addTextChangedListener(
            sampleSearchWatcher
        )
        sampleListView = binding.sampleListView
        sampleAdapter = SampleAdapter(this, sampleList)
        sampleAdapter.onCheckBoxStateChanged = { position, isChecked, item ->
            neuronAdapter.updateData(isChecked, item)
        }
        sampleListView.adapter = sampleAdapter
        httpData.sampleList = sampleList;
        httpData.fetchSampleData(sampleAdapter, originSampleList);


    }

    private fun showToast(message: String) {
        Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
    }

    /**
     * A native method that is implemented by the 'neuronview' native library,
     * which is packaged with this application.
     */
    external fun stringFromJNI(): String

    companion object {
        // Used to load the 'neuronview' library on application startup.
        init {
            System.loadLibrary("neuronview")
        }
    }
}

